package com.young.dbcp.config.durid;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Configuration
public class DruidConfig {

    private static final Logger log = LoggerFactory.getLogger(DruidConfig.class);

    @Value("${spring.datasource.druid.stat-view-servlet.loginUsername}")
    private String userName;

    @Value("${spring.datasource.druid.stat-view-servlet.loginPassword}")
    private String password;

    @Value("${spring.datasource.druid.stat-view-servlet.allow}")
    private String allowIp;

    /**
     * 必须配置数据源，不然无法获取到sql监控，与sql防火墙监控
     */
    @Bean(name = "default_databaseSource")
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource druidDataSource() {
        //DruidDataSource build = new DruidDataSource();
        // 或者
        DruidDataSource build = DruidDataSourceBuilder.create().build();
        //配置拦截器，添慢sql以及日志拦截器
        List<Filter> filters = new ArrayList<>();
        filters.add(statFilter());
        filters.add(logFilter());
        build.setProxyFilters(filters);
        return build;
    }

    /**
     * @description 注册一个StatViewServlet,进行druid监控页面配置
     * @return servlet registration bean
     *
     * 这里面的配置都可以在application-durid.properties中找到对应的配置
     */
    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        log.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
        servletRegistrationBean.setServlet(new StatViewServlet());
        servletRegistrationBean.addUrlMappings("/druid/*");
        Map<String, String> initParameters = new HashMap<>();
        initParameters.put("loginUsername", userName);// 用户名
        initParameters.put("loginPassword", password);// 密码
        initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能
        //initParameters.put("allow", allowIp); // IP白名单 (没有配置或者为空，则允许所有访问)
        //initParameters.put("deny", "");// IP黑名单 (存在共同时，deny优先于allow)
        servletRegistrationBean.setInitParameters(initParameters);
        return servletRegistrationBean;
    }


    /**
     * @description 注册一个过滤器，允许页面正常浏览
     * @return filter registration bean
     *
     * 这里面的配置都可以在application-durid.properties中找到对应的配置
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }


    /**
     * @return
     * @description 配置慢sql拦截器
     */
    @Bean(name = "statFilter")
    public StatFilter statFilter() {
        StatFilter statFilter = new StatFilter();
        //慢sql时间设置,即执行时间大于200毫秒的都是慢sql
        statFilter.setSlowSqlMillis(30);
        statFilter.setLogSlowSql(true);
        statFilter.setMergeSql(true);
        return statFilter;
    }

    /**
     * @return
     * @description 配置日志拦截器
     */
    @Bean(name = "logFilter")
    public Slf4jLogFilter logFilter() {
        Slf4jLogFilter slf4jLogFilter = new Slf4jLogFilter();
        slf4jLogFilter.setDataSourceLogEnabled(true);
        slf4jLogFilter.setStatementExecutableSqlLogEnable(true);
        return slf4jLogFilter;
    }
}
